package com.wmwsystems.inc.demo.wsserver;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.embedded.ServletRegistrationBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.ws.config.annotation.EnableWs;
import org.springframework.ws.config.annotation.WsConfigurerAdapter;
import org.springframework.ws.server.EndpointInterceptor;
import org.springframework.ws.soap.security.wss4j.Wss4jSecurityInterceptor;
import org.springframework.ws.soap.security.wss4j.callback.SimplePasswordValidationCallbackHandler;
import org.springframework.ws.transport.http.MessageDispatcherServlet;
import org.springframework.ws.wsdl.wsdl11.DefaultWsdl11Definition;
import org.springframework.xml.xsd.SimpleXsdSchema;
import org.springframework.xml.xsd.XsdSchema;

import java.util.List;
import java.util.Properties;

@EnableWs
@Configuration
public class WebServiceConfig extends WsConfigurerAdapter {

    @Autowired
    private Wss4jSecurityInterceptor wsServerSecurityInterceptor;

    @Override
    public void addInterceptors(List<EndpointInterceptor> interceptors) {
        interceptors.add(wsServerSecurityInterceptor);
    }

    @Bean
    public Wss4jSecurityInterceptor wsServerSecurityInterceptor(SimplePasswordValidationCallbackHandler handler) {

        Wss4jSecurityInterceptor interceptor = new Wss4jSecurityInterceptor();
        interceptor.setValidationActions("UsernameToken");
        interceptor.setValidationCallbackHandler(handler);
        return interceptor;
    }

    @Bean
    SimplePasswordValidationCallbackHandler simplePasswordValidationCallbackHandler() {
        SimplePasswordValidationCallbackHandler handler = new SimplePasswordValidationCallbackHandler();
        Properties users = new Properties();
        users.setProperty("2", "outgoingpassword");
        handler.setUsers(users);
        return handler;
    }

    @Bean
    public ServletRegistrationBean dispatcherServlet(ApplicationContext applicationContext) { //naming dispatcherServlet it replaces Spring Boot's default DispatcherServlet
        MessageDispatcherServlet servlet = new MessageDispatcherServlet(); //servlet for WS
        servlet.setApplicationContext(applicationContext); //needed for detecting Spring Beans
        servlet.setTransformWsdlLocations(true); //transform hostnames in WSDL
        return new ServletRegistrationBean(servlet, "/ws/*");
    }

    @Bean(name = "flights") //bean name determines URL -> /ws/flights
    public DefaultWsdl11Definition wsdl11Definition(XsdSchema flightsSchema) {
        DefaultWsdl11Definition wsdl11Definition = new DefaultWsdl11Definition();
        wsdl11Definition.setPortTypeName("FlightsPort");
        wsdl11Definition.setLocationUri("/ws");
        wsdl11Definition.setTargetNamespace("http://wmwsystems.com/service/flights");
        wsdl11Definition.setSchema(flightsSchema);
        return wsdl11Definition;
    }

    @Bean
    public XsdSchema flightsSchema() {
        return new SimpleXsdSchema(new ClassPathResource("flights.xsd"));
    }
}
